#!/usr/bin/python
import os, sys
import subprocess
from datetime import datetime
from package import const
from package.models import Module, PackageName, Package, FixedBug, ChangedPackage, Dependancy, OSRelease

CATEGORY = 'Category'
NAME = 'Name'
FLAG = 'Flag'
VERSION = 'Version'
OS_RELEASE = 'os_release'
BUILD = 'build'
cwd = os.path.dirname(__file__)
pkg_list_path = cwd + '/pkg_list/'
log_path = cwd + '/log/'
error_log_file_prefix = 'package_error_'
log_file = 'package.log'
pkg_list_file = pkg_list_path + 'pkg_{0}_b{1}_full.list'
build_log_info = 'in {0} build {1}'
pkg_log_info = 'package <{0}> in {1} build {2}'

def error_log(task, description, cause):
    log_handler = open(
        '{0}{1}{2}.log'.format(log_path, error_log_file_prefix, datetime.now().strftime('%Y-%m-%d')),
        'a'
    ) #package_error_2013_02_12.log
    log = ''
    log += 'task: ' + task + '\n'
    log += 'description: ' + description + '\n'
    log += 'cause: ' + cause + '\n'
    log += 'time: ' + datetime.now().strftime('%H:%M:%S') + '\n\n'
    log_handler.write(log)
    sys.stderr.write(log)
    log_handler.close()

def read_file(path):
    handler = open(path)
    data = handler.read()
    handler.close()
    return data

def log(task, status):
    log_handler = open(log_path + log_file, 'a')
    log = ''
    log += 'task: ' + task + '\n'
    log += 'status: ' + status + '\n'
    log += 'time: ' + datetime.now().strftime('%Y-%m-%d-%H:%M:%S') + '\n\n'
    log_handler.write(log)
    print log
    log_handler.close()

def run_bash(command):
    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    #return (stdout,stderr) from diff
    return p.communicate()

def find_one_from_dicts(dicts, condictions):
    for di in dicts:
        satisfied = True
        for k,v in condictions.items():
            if v != di.get(k):
                satisfied = False
        if satisfied:
            return di
    return None

def get_last_build(os_release_str, current_build):
    current_build_num = int(current_build)
    last_build = None
    while current_build_num > 0:
        last_build_num = current_build_num - 1
        last_build_str = '0'+str(last_build_num) if last_build_num < 10 else str(last_build_num)
        last_build_file = pkg_list_file.format(os_release_str, last_build_str) 
        if os.path.isfile(last_build_file):
            last_build = last_build_str
            break
        current_build_num = last_build_num
    return last_build

def get_columns_from_dict(line_dict):
    category  = line_dict[CATEGORY]
    name = line_dict[NAME]
    version = line_dict[VERSION]
    flag = line_dict[FLAG]
    layer,module= category.split('/')
    return [name, version, flag, layer, module]

def halt(task):
        log(task, 'fail')
        exit(-1)
    

def get_dict_from_line(line):
    return dict(tuple(item.split(': ')) for item in line.strip('< >').split('****'))

def get_layer_int(task, layer_str):
    layer =  const.LAYERS.get(layer_str)
    if not layer:
        error_log(task, 'layer does not exist in const.LAYERS', layer_str)
        halt(task)
    return layer

#db
def create_package(task, pkg_dict, os_release, build):
    #get all columns from pkg dict
    name, version, flag, layer_str, module = get_columns_from_dict(pkg_dict)
    #get layer int, because layer is installed as integer
    layer = get_layer_int(task, layer_str)
    os_release,created = OSRelease.objects.get_or_create(name=os_release)
    pkg_name, created = PackageName.objects.get_or_create(name=name, is_normal=True)
    module, created = Module.objects.get_or_create(name=module, layer=layer)
    pkg, created = Package.objects.get_or_create(
        package_name=pkg_name, module=module, os_release=os_release,
        change_in_build=build, version=version, change_flag=const.CHANGE_FLAGS[flag]
    )
    if not created:
        error_log(
            task, 'new added package repeated',
            pkg_log_info.format(name, os_release, build)
        )

